Add a `harness` manifest option
authorAlex Crichton <alex@alexcrichton.com>
Mon, 25 Aug 2014 12:54:47 +0000 (05:54 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Wed, 27 Aug 2014 01:51:47 +0000 (18:51 -0700)
This option is used to disable the --test flag to rustc for a test or benchmark
target in order to signal that the binary already knows how to run the testing
infrastructure.

The test/benchmark is still compiled and run as usual, and the exit code is
expected to reflect the result of the test/benchmark.

Closes #431

src/cargo/core/manifest.rs
src/cargo/ops/cargo_rustc/mod.rs
src/cargo/util/toml.rs
tests/test_cargo_test.rs

index fe590f119eb3e797b0c9f862fa774e4385eee967..174e751aa8b22add9930a3b28311919ccfd70445 100644 (file)
@@ -114,6 +114,7 @@ pub struct Profile {
     doc: bool,
     dest: Option<String>,
     plugin: bool,
+    harness: bool, // whether to use the test harness (--test)
 }
 
 impl Profile {
@@ -127,6 +128,7 @@ impl Profile {
             dest: None,
             plugin: false,
             doctest: false,
+            harness: true,
         }
     }
 
@@ -189,6 +191,10 @@ impl Profile {
         self.test
     }
 
+    pub fn uses_test_harness(&self) -> bool {
+        self.harness
+    }
+
     pub fn is_doctest(&self) -> bool {
         self.doctest
     }
@@ -242,6 +248,11 @@ impl Profile {
         self.plugin = plugin;
         self
     }
+
+    pub fn harness(mut self, harness: bool) -> Profile {
+        self.harness = harness;
+        self
+    }
 }
 
 impl<H: hash::Writer> hash::Hash<H> for Profile {
@@ -253,6 +264,7 @@ impl<H: hash::Writer> hash::Hash<H> for Profile {
             debug,
             plugin,
             dest: ref dest,
+            harness: harness,
 
             // test flags are separated by file, not by profile hash, and
             // env/doc also don't matter for the actual contents of the output
@@ -262,7 +274,7 @@ impl<H: hash::Writer> hash::Hash<H> for Profile {
             test: _,
             doctest: _,
         } = *self;
-        (opt_level, debug, plugin, dest).hash(into)
+        (opt_level, debug, plugin, dest, harness).hash(into)
     }
 }
 
index a4644e1747b4b75bdb91620fc740fa41ad5519b5..6b725426738801e9cbf9f322bb2ced3fadaedf2d 100644 (file)
@@ -310,7 +310,7 @@ fn build_base_args(mut cmd: ProcessBuilder,
         cmd = cmd.args(["--cfg", "ndebug"]);
     }
 
-    if profile.is_test() {
+    if profile.is_test() && profile.uses_test_harness() {
         cmd = cmd.arg("--test");
     }
 
index 03445dccd8bbfe9617179f8857b54934e5abbbe9..d205af3af9eb17e4d38880d5e08336702d8c90a1 100644 (file)
@@ -500,6 +500,7 @@ struct TomlTarget {
     bench: Option<bool>,
     doc: Option<bool>,
     plugin: Option<bool>,
+    harness: Option<bool>,
 }
 
 #[deriving(Decodable,Encodable,PartialEq,Clone)]
@@ -519,6 +520,7 @@ impl TomlTarget {
             bench: None,
             doc: None,
             plugin: None,
+            harness: None,
         }
     }
 }
@@ -660,12 +662,13 @@ fn normalize(libs: &[TomlLibTarget],
             let path = test.path.clone().unwrap_or_else(|| {
                 TomlString(default(test))
             });
+            let harness = test.harness.unwrap_or(true);
 
             // make sure this metadata is different from any same-named libs.
             let mut metadata = metadata.clone();
             metadata.mix(&format!("test-{}", test.name));
 
-            let profile = &Profile::default_test();
+            let profile = &Profile::default_test().harness(harness);
             dst.push(Target::test_target(test.name.as_slice(),
                                          &path.to_path(),
                                          profile,
@@ -680,12 +683,13 @@ fn normalize(libs: &[TomlLibTarget],
             let path = bench.path.clone().unwrap_or_else(|| {
                 TomlString(default(bench))
             });
+            let harness = bench.harness.unwrap_or(true);
 
             // make sure this metadata is different from any same-named libs.
             let mut metadata = metadata.clone();
             metadata.mix(&format!("bench-{}", bench.name));
 
-            let profile = &Profile::default_bench();
+            let profile = &Profile::default_bench().harness(harness);
             dst.push(Target::bench_target(bench.name.as_slice(),
                                          &path.to_path(),
                                          profile,
index cd172fe7da9a07aaac18e2597621de1f2d23e09b..f6f492389735be53da6a0536a39d625f4e1ac4d3 100644 (file)
@@ -874,3 +874,33 @@ test!(test_no_run {
                        compiling = COMPILING,
                        dir = p.url()).as_slice()));
 })
+
+test!(test_no_harness {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [package]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+
+            [[bin]]
+            name = "foo"
+            test = false
+
+            [[test]]
+            name = "bar"
+            path = "foo.rs"
+            harness = false
+        "#)
+        .file("src/main.rs", "fn main() {}")
+        .file("foo.rs", "fn main() {}");
+
+    assert_that(p.cargo_process("test"),
+                execs().with_status(0)
+                       .with_stdout(format!("\
+{compiling} foo v0.0.1 ({dir})
+{running} target[..]bar-[..]
+",
+                       compiling = COMPILING, running = RUNNING,
+                       dir = p.url()).as_slice()));
+})